package by.parfen.game.websocket;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/websocket-game", configurator = WebSocketConfigurator.class)
public class WebSocketEndpoint {

	private static final Logger LOGGER = Logger.getLogger(WebSocketEndpoint.class.getName());
	private static final String GAME_PORTAL_NAME = "firstGame";

	private Session wsSession;
	private HttpSession httpSession;
	// private GamePortalCoder gamePortalCoder;

	private static Set<Session> wsSessions = Collections.synchronizedSet(new HashSet<Session>());
	private static Map<String, Session> wsSessionsMap = Collections.synchronizedMap(new HashMap<String, Session>());
	private static Map<String, HttpSession> httpSessionsMap = Collections
			.synchronizedMap(new HashMap<String, HttpSession>());

	// private static GamePortal gamePortal;

	@OnOpen
	public void onOpen(Session session, EndpointConfig config) {

		this.wsSession = session;
		this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
		// this.gamePortalCoder = new GamePortalCoderImpl();

		wsSessions.add(session);
		wsSessionsMap.put(this.httpSession.getId(), this.wsSession);
		httpSessionsMap.put(this.httpSession.getId(), this.httpSession);

		System.out.println("NEW Websocket Session: " + this.wsSession.getId());
		System.out.println("NEW HTTP Session: " + this.httpSession.getId());
		System.out.println("wsSessionMap: " + wsSessionsMap);
		System.out.println("httpSessionMap: " + httpSessionsMap);

		this.httpSession.setAttribute("countOfSession", httpSessionsMap.size());
		System.out.println("httpSessionsMap.size: " + httpSessionsMap.size());

		this.httpSession.setAttribute("httpSessionsMap", httpSessionsMap);
		LOGGER.info("added Map as session attribute");

	}

	@OnClose
	public void onClose(Session session) {
		wsSessions.remove(session);
		wsSessionsMap.remove(this.httpSession.getId());
		httpSessionsMap.remove(this.httpSession.getId());
		System.out
				.println("Websocket session " + session.getId() + " has ended, HTTP Session: " + this.httpSession.getId());
		this.httpSession.setAttribute("countOfSession", httpSessionsMap.size());
		this.httpSession.setAttribute("httpSessionsMap", httpSessionsMap);
	}

	@OnMessage
	public void onMessage(String message, Session session) throws IOException {
		if ("GET_INFO".equals(message)) {
			wsSession.getBasicRemote().sendText("Try to get info...");
		} else {
			wsSession.getBasicRemote().sendText(message);
			LOGGER.info("WS-Game, last user: " + this.httpSession.getAttribute("lastUser"));

			synchronized (wsSessions) {
				// Iterate over the connected sessions
				// and broadcast the received message
				for (Session wsSession : wsSessions) {
					if (!wsSession.equals(session)) {
						try {
							wsSession.getBasicRemote().sendText(message);
						} catch (IOException ex) {
							ex.printStackTrace();
						}
					}
				}
			}
		}
	}

}